/// @tags: Subset Exclusion
#include <cstdio>
#include <iostream>
#define rint register int

using std::cin;
using std::cout;

namespace BlueQuantum {

typedef long long LL;

constexpr int maxn = 16, maxm = maxn * maxn, maxs = 1 << 15, mod = 1e9 + 7;

int e[maxn][maxn], f[3][maxs], rel[maxs], ind[maxs], qpow[maxm], popcnt[maxs];

inline int main() {
  int n, m;
  cin >> n >> m;
  qpow[0] = 1;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    e[u][v]++;
    qpow[i] = (qpow[i - 1] + qpow[i - 1]) % mod;
  }
  int slim = 1 << n;
  for (int s = 0; s < slim; ++s)
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n; ++j)
        if (e[i][j]) {
          if (((s >> (i - 1)) & 1) && ((s >> (j - 1)) & 1)) rel[s] += e[i][j];
          if (((s >> (i - 1)) & 1) || ((s >> (j - 1)) & 1)) ind[s] += e[i][j];
        }
  for (int i = 1; i <= 2; ++i)
    for (int s = 0; s < slim; ++s) {
      if (!((s >> (i - 1)) & 1)) continue;
      f[i][s] = qpow[rel[s]];
      for (int t = (s - 1) & s; t; t = (t - 1) & s) {
        if (!((t >> (i - 1)) & 1)) continue;
        f[i][s] = (f[i][s] - (LL)f[i][t] * qpow[rel[s ^ t]] % mod + mod) % mod;
      }
    }
  int ans = qpow[m];
  for (int s = 0; s < slim; ++s) {
    if (!(s & 1) || (s >> 1 & 1)) continue;
    for (int t = (slim - 1) ^ s; t; t = (t - 1) & ((slim - 1) ^ s)) {
      if (!(t >> 1 & 1) || rel[s] + rel[t] < rel[s | t]) continue;
      ans = (ans - (LL)f[1][s] * f[2][t] % mod * qpow[m - ind[s | t]] % mod + mod) % mod;
    }
  }
  cout << ans;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("AT3634 Nice to Meet You.in", "r", stdin);
  freopen("AT3634 Nice to Meet You.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
